package com.glorysoft.xztpda.base

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.lifecycle.lifecycleOwner
import com.glorysoft.xztpda.utils.MyUtils
import com.glorysoft.xztpda.R
import com.gyf.barlibrary.ImmersionBar
import com.huawei.hms.hmsscankit.ScanUtil
import com.huawei.hms.ml.scan.HmsScan
import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions
import com.pda.platform.ui.ui_pdaplatform.activity_public.FreeUI_QRCodeActivity
import com.pda.platform.ui.ui_pdaplatform.utils_public.FreeApi_ActivityManager
import com.pda.platform.ui.ui_pdaplatform.utils_public.FreeApi_EditTextUtils
import com.pda.platform.ui.ui_pdaplatform.utils_public.FreeApi_ToastUtils
import kotlinx.android.synthetic.main.activity_title.*
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.util.ArrayList

abstract class BaseActivity<VM : BaseViewModel, DB : ViewDataBinding> : AppCompatActivity(),
    IBaseView {

    protected lateinit var viewModel: VM

    protected lateinit var mBinding: DB

    private var dialog: MaterialDialog? = null

    private var mImmersionBar: ImmersionBar? = null



    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        FreeApi_ActivityManager.getActivityManager().addActivity(this)
        initViewDataBinding()
        ImmersionBar.with(this).statusBarDarkFont(true).init()
        //强制竖屏
//        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        initViewTitle()
        //注册 UI事件
        lifecycle.addObserver(viewModel)
        registerDefUIChange()
        initView(savedInstanceState)
        initData()
    }

    override fun onDestroy() {
        super.onDestroy()
        ImmersionBar.with(this).statusBarDarkFont(true).destroy()
        FreeApi_ActivityManager.getActivityManager().finishActivity(this)
    }

    abstract fun layoutId(): Int
    abstract fun initVariableId(): Int
    abstract fun initView(savedInstanceState: Bundle?)
    abstract fun initData()


    /**
     * DataBinding or ViewBinding
     */
    private fun initViewDataBinding() {
        val type = javaClass.genericSuperclass
        if (type is ParameterizedType) {
            val cls = type.actualTypeArguments[1] as Class<*>
            when {
                ViewDataBinding::class.java.isAssignableFrom(cls) && cls != ViewDataBinding::class.java -> {
                    if (layoutId() == 0) throw IllegalArgumentException("Using DataBinding requires overriding method layoutId")
                    mBinding = DataBindingUtil.setContentView(this, layoutId())
                    (mBinding as ViewDataBinding).lifecycleOwner = this
                }
                ViewBinding::class.java.isAssignableFrom(cls) && cls != ViewBinding::class.java -> {
                    cls.getDeclaredMethod("inflate", LayoutInflater::class.java).let {
                        @Suppress("UNCHECKED_CAST")
                        mBinding = it.invoke(null, layoutInflater) as DB
                        setContentView(mBinding.root)
                    }
                }
                else -> {
                    if (layoutId() == 0) throw IllegalArgumentException("If you don't use ViewBinding, you need to override method layoutId")
                    setContentView(layoutId())
                }
            }
            createViewModel(type.actualTypeArguments[0])
            //关联ViewModel
            mBinding.setVariable(initVariableId(), viewModel)
        } else throw IllegalArgumentException("Generic error")
    }

    fun startScanForCode(context: Activity,code: Int) {
//        val intent = Intent(context, FreeUI_QRCodeActivity::class.java)
        //设置横屏
//        intent.putExtra("screenOrientation",1)
//        startActivityForResult(intent,code)

        // 申请权限之后，调用DefaultView扫码界面。
        ScanUtil.startScan(
            context,
            code,
            HmsScanAnalyzerOptions.Creator().setHmsScanTypes(HmsScan.ALL_SCAN_TYPE).create()
        )
    }

    /**
     * 注册 UI 事件
     */
    private fun registerDefUIChange() {
        viewModel.defUI.showDialog.observe(this, {
            showLoading()
        })
        viewModel.defUI.dismissDialog.observe(this, {
            dismissLoading()
        })
        viewModel.defUI.toastEvent.observe(this, {
            FreeApi_ToastUtils.showFreeToast(it.message, this, it.isOk, 0)
        })
    }
    /**
     * 打开等待框
     */
    open fun showLoading() {
        (dialog ?: MaterialDialog(this)
            .cancelable(false)
            .cornerRadius(8f)
            .customView(R.layout.free_ui_glory_dialog_loading, noVerticalPadding = false)
            .lifecycleOwner(this)
            .maxWidth(R.dimen.dialog_width).also {
                dialog = it
            })
            .show()

    }

    /**
     * 关闭等待框
     */
    private fun dismissLoading() {
        dialog?.run { if (isShowing) dismiss() }
    }

    protected open fun addActivity(activity: Activity) {
        Constant.mActivityList.add(activity)
    }

    protected open fun finishAllActivity() {
        for (data in Constant.mActivityList) {
            data.finish()
        }
    }


    /**
     * 创建 ViewModel
     */
    @Suppress("UNCHECKED_CAST")
    fun createViewModel(type: Type) {
        val tClass = type as? Class<VM> ?: BaseViewModel::class.java
        viewModel = ViewModelProvider(viewModelStore, defaultViewModelProviderFactory)
            .get(tClass) as VM
    }

    //
    override fun getDefaultViewModelProviderFactory(): ViewModelProvider.Factory {
        return MvvmConfig.getConfig().viewModelFactory()
            ?: super.getDefaultViewModelProviderFactory()
    }

    /**
     * 设置标题
     *
     * @param title
     */
    open fun setTitle(title: String) {
        if (tvTitle != null) {
            tvTitle.text = title
        }
    }

    open fun setRightListener(title: String, listener: View.OnClickListener?) {
        if (title.isNotEmpty()) {
            tvRight.visibility = View.VISIBLE
            tvRight.text = title
            tvRight.setOnClickListener(listener)
        } else {
            tvRight.visibility = View.GONE
        }
    }

    open fun setRightListener(resID: Int, listener: View.OnClickListener?) {
        if (resID > 0) {
            ivRight.visibility = View.VISIBLE
            ivRight.setImageResource(resID)
            ivRight.setOnClickListener(listener)
        } else {
            ivRight.visibility = View.GONE
        }
    }

    /**
     * 跳转界面
     *
     * @param c 目标Activity
     */
    open fun startActivity(c: Class<*>?) {
        startActivity(Intent(this, c))
    }

    /**
     * 携带数据跳转界面
     *
     * @param c      目标Activity
     * @param bundle 携带数据
     */
    open fun startActivity(c: Class<*>?, bundle: Bundle?) {
        val intent = Intent(this, c)
        intent.putExtras(bundle!!)
        startActivity(intent)
    }

    override fun initViewTitle() {
        if (ivBack != null) {
            ivBack.setOnClickListener { finish() }
        }

        if (tvCurrentUser != null) {
            tvCurrentUser.text = Constant.CURRENT_USER
        }

    }

    /**
     * 不获取焦点初始化editText
     * @param editText
     * @param listener
     * @param
     */
    protected open fun initEdit(
        editText: EditText,
        listener: EditTextListener
    ) {
        MyUtils.initEnterToUpperCase(editText,listener)
        FreeApi_EditTextUtils.setEditTextListener(editText, this) { s: String ->
            listener.onTextChangeListener(s.replace(" ",""))
        }
    }

    override fun initParam() {
    }

    interface EditTextListener {
        fun onTextChangeListener(s: String)
    }
}